Unity 打开安卓相册和相机所遇到的问题

Unity在接入安卓的打开相册和相机时遇到了很多意想不到的问题。
首先,我用的是Unity 5.5.3p1,跟我以前用的4.x版本相差甚远,之前的jar,变成了aar,然后Android Studio没有怎么使用过,遇到了好多SDK方面的错误。
我把android 项目弄好了导出aar,导入Unity 中后又遇到了导不出apk的情况。这个问题解决完成后,测试不同的手机,结果发现小米的打开相册后会把原有的Activity注销掉,导致打开相册的重启。
实在是令人头疼的一系列事情。
小米手机还有一个存储图片的问题,这个问题是在裁剪完成后,先保存本地的一个临时文件,然后在用临时文件生成base64,传递给Unity。
这里和雨松MOMO的做法不同,雨松是裁剪完后存储到Unity 所访问的位置,我是直接传递base64了。
现小米打开相册后销毁原Activity 的问题还未解决。
最后打开相册或相机的代码,仅供参考:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
public class WebViewActivity extends Activity {
public static final int NONE = 0;
public static final int PHOTOHRAPH = 1;// 拍照
public static final int PHOTOZOOM = 2; // 缩放
public static final int PHOTORESOULT = 3;// 结果
public final static int IMAGE_SIZE = 500;
public static final String IMAGE_UNSPECIFIED = "image/*";
public final static String FILE_NOTGET = "FILE_NOTGET";
public static String FILE_BASE64 = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
String type = this.getIntent().getStringExtra("type");
//在这里判断是打开本地相册还是直接照相
if(type.equals("takePhoto"))
{
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(Environment.getExternalStorageDirectory(), "temp.jpg")));
startActivityForResult(intent, PHOTOHRAPH);
}else
{
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, IMAGE_UNSPECIFIED);
startActivityForResult(intent, PHOTOZOOM);
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if (resultCode == NONE)
{
if(data == null)
{
UnityPlayer.UnitySendMessage("Main Camera","message",FILE_NOTGET);
this.finish();
}else
{
if(this.isFinishing() == false)
{
this.finish();
}
UnityPlayer.UnitySendMessage("Main Camera","message",FILE_NOTGET);
}
return;
}
// 拍照
if (requestCode == PHOTOHRAPH) {
//设置文件保存路径这里放在跟目录下
File picture = new File(Environment.getExternalStorageDirectory() + "/temp.jpg");
Uri testURi = Uri.fromFile(picture);
if (testURi != null) {
startPhotoZoom_New(testURi,IMAGE_SIZE);
} else {
UnityPlayer.UnitySendMessage("Main Camera","message",FILE_NOTGET);
}
}
if (requestCode != PHOTOHRAPH) {
if (data == null) {
UnityPlayer.UnitySendMessage("Main Camera", "message", FILE_NOTGET);
this.finish();
}
}else
{
if(data == null)
{
return;
}
}
// 读取相册缩放图片
if (requestCode == PHOTOZOOM) {
Uri galleryPhotoUri = data.getData();
startPhotoZoom_New(galleryPhotoUri,IMAGE_SIZE);
}
// 处理结果
if (requestCode == PHOTORESOULT) {
File picture = new File(Environment.getExternalStorageDirectory().getPath() + "/" + "small.jpg");
Uri getUri = Uri.fromFile(picture);
if(getUri != null)
{
Bitmap getBitmap = convertBM(getUri);
try{
FILE_BASE64 = bitmapToBase64(getBitmap);
UnityPlayer.UnitySendMessage("Main Camera","message",FILE_BASE64);
this.finish();
}catch (Exception ex)
{
Log.i("abc",ex.getMessage());
ex.printStackTrace();
}
}
}
super.onActivityResult(requestCode, resultCode, data);
}
private Bitmap convertBM(Uri uri)
{
InputStream is;
try {
//Uri ----> InputStream
is = getContentResolver().openInputStream(uri);
//InputStream ----> Bitmap
Bitmap bm = BitmapFactory.decodeStream(is);
//关闭流
is.close();
return bm;
} catch (FileNotFoundException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
public String bitmapToBase64(Bitmap bitmap) {
String result = null;
ByteArrayOutputStream baos = null;
try {
if (bitmap != null) {
baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
baos.flush();
baos.close();
byte[] bitmapBytes = baos.toByteArray();
result = Base64.encodeToString(bitmapBytes, Base64.DEFAULT);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (baos != null) {
baos.flush();
baos.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return result;
}
public static Bitmap base64ToBitmap(String base64Data) {
byte[] bytes = Base64.decode(base64Data, Base64.DEFAULT);
return BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
}
/**
* 裁剪图片
*/
private void startPhotoZoom_New(Uri uri, int size) {
Intent intent = new Intent("com.android.camera.action.CROP");
intent.setDataAndType(uri, "image/*");
// crop为true是设置在开启的intent中设置显示的view可以剪裁
intent.putExtra("crop", "true");
// aspectX aspectY 是宽高的比例
intent.putExtra("aspectX", 1);
intent.putExtra("aspectY", 1);
// outputX,outputY 是剪裁图片的宽高
intent.putExtra("outputX", size);
intent.putExtra("outputY", size);
/**
* 此方法返回的图片只能是小图片(sumsang测试为高宽160px的图片)
* 故将图片保存在Uri中,调用时将Uri转换为Bitmap,此方法还可解决miui系统不能return data的问题
*/
Uri uritempFile = Uri.parse("file:///" + Environment.getExternalStorageDirectory().getPath() + "/" + "small.jpg");
intent.putExtra(MediaStore.EXTRA_OUTPUT, uritempFile);
intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
startActivityForResult(intent, PHOTORESOULT);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event)
{
if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0)
{
UnityPlayer.UnitySendMessage("Main Camera","message",FILE_BASE64);
}
return super.onKeyDown(keyCode, event);
}
}

坚持原创技术分享,您的支持将鼓励我继续创作!